/**
 * @author: Liu SongJian
 * @version: 2.6
 * 开发文档（wiki）：http://wiki.cy.com/display/wzhdkf/ja+v2.6
 **/
'use strict';

(function (window) {
    var name = 'ja',

        version = '2.6',

        arrHost = [             // 请求通用域名(//join-activity.changyou.com) 接口
            'kzgj.cy.com'
        ],

        arrExt = ['json', 'png', 'jpg', 'gif', 'js'],   // 请求非接口文件后缀

        debugDomain = [         // isDebug 生效域名
            'local-activity.changyou.com',
            'local-join-activity.changyou.com',
            'dev-activity.changyou.com'
        ],

        vconsoleDomain = [      // isVConsole 生效域名
            'local-activity.changyou.com',
            'local-join-activity.changyou.com',
            'dev-activity.changyou.com',
            'test-activity.changyou.com'
        ],

        imgHost = '//i0.cy.com',

        webHost = location.host,

        origin = location.origin || location.protocol + '//' + webHost,

        env = {
            'local-activity.changyou.com': {
                staticUrl: '//local-static2.changyou.com',
                env: 'local'
            },
            'local-join-activity.changyou.com': {
                staticUrl: '//local-static2.changyou.com',
                env: 'local'
            },
            'dev-activity.changyou.com': {
                staticUrl: '//dev-static2.changyou.com',
                env: 'dev'
            },
            'test-activity.changyou.com': {
                staticUrl: '//test-static2.changyou.com',
                env: 'test'
            }
        },

        staticOrigin = env[webHost] ? env[webHost].staticUrl : '//static2.changyou.com',

        urlWxBind = (env[webHost] || webHost.indexOf('local-') > -1 ? origin : '//tlus.changyou.com') + '/xtl/wxBind/20180910/mobile/index.html',

        urlWxBindHj = (env[webHost] || webHost.indexOf('local-') > -1 ? origin : '//tlhj-us.changyou.com') + '/tlhj/wxBind/20201123/mobile/index.html',

        isIos = /iphone|ipod|ipad/i.test(window.navigator.userAgent.toLowerCase()),

        isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),

        isWegame = /wegame/i.test(navigator.userAgent),

        isComWx = /wxwork/i.test(navigator.userAgent),  // 企业微信

        isWechat = window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger' && !isComWx,

        timerTips;

    /**
     * == 全局对象 ==
     *   glob 为全局状态管理，包含所有内部状态
     *   _glob 只包含初始化回调对象
     **/
    var glob = {
        pendingRequests: {},
        isWxReady: undefined        // wx.config 是否完成
    };
    var _glob = {
        code: undefined,            // 活动信息 landing/init 返回code
        isIos: isIos,
        isMobile: isMobile,
        isWechat: isWechat,
        isComWx: isComWx,
        isWegame: isWegame,
        urlWxBind: urlWxBind,
        urlWxBindHj: urlWxBindHj,
        staticOrigin: staticOrigin,
        params: {},
        env: env[webHost] ? env[webHost].env : 'prod',
        isLogin: undefined,         // 是否登录
        isWLogin: undefined,        // 是否微信登录
        userInfo: undefined,        // 账号信息
        wechatInfo: undefined,      // 微信账号信息
        wxBindName: undefined,    // 微信绑定账号昵称
        wxBindType: undefined      // 微信绑定账号类型
    };

    // 构造函数合并
    function Mixin(recClass, giveClass) {
        if (arguments.length > 2) {
            for (var i = 2; i < arguments.length; ++i) {
                var name = arguments[i];
                recClass.prototype[name] = giveClass.prototype[name];
            }
        } else {
            for (var key in giveClass.prototype) {
                if (!recClass.prototype[key]) {
                    recClass.prototype[key] = giveClass.prototype[key];
                }
            }
        }
    }

    // 新旧版本方法合并
    function MixinDeep(recClass, giveClass) {
        for (var key in giveClass.prototype) {
            if (recClass.prototype[key]) {
                $.extend(recClass.prototype[key], giveClass.prototype[key])
            }else {
                recClass.prototype[key] = giveClass.prototype[key];
            }
        }
    }

    // 旧版本直接挂载ja方法
    function MixinSimple(recClass, giveClass, module) {
        if (arguments.length > 3) {
            for (var i = 3; i < arguments.length; ++i) {
                var name = arguments[i];
                recClass.prototype[name] = giveClass.prototype[module][name];
            }
        }
    }

    // xhr 兼容写法
    function createXhr(){
        if(typeof XMLHttpRequest !== "undefined"){
            return new XMLHttpRequest();
        }else if(typeof ActiveXObject !== "undefined"){
            var verStr = [
                "MSXML.XMLHttp.6.0",
                "MSXML.XMLHttp.3.0",
                "MSXML.XMLHttp"];
            for(var n in verStr){
                try{
                    var xhr = new ActiveXObject(verStr[n]);
                    return xhr;
                }catch(e){
                    console.log(e);
                }
            }
        }else{
            console.log("sorry,您的计算机不支持ajax通信！");
        }
    }

    // jquery ajax 默认选项设置
    function setupAjax() {
        var ajaxHeaders = {
            'Authorization': glob.token,
            'APP': glob.app,
            'ACTIVITY': glob.activity,
            'VERSIONCODE': glob.version,
            'PLAT': glob.platform,
            'CYSCID': glob.cyscid,
            'CYSTID': glob.cystid,
            'LOGINTYPE': storage.getLoginType() || undefined
        };

        $.ajaxSetup({
            dataType: 'json',
            cache: false,
            xhrFields: {withCredentials: true},
            headers: ajaxHeaders
        })
    }

    // jquery ajax 处理
    $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
        var ajaxUrl = options.url.indexOf('?')
                ? options.url.split('?')[0] : options.url,
            portName = ajaxUrl.substr(ajaxUrl.lastIndexOf('/') + 1),
            ext = portName.lastIndexOf('.') !== -1
                ? portName.substr(portName.lastIndexOf('.') + 1) : null,
            keyName = options.data ? ajaxUrl + '?' + options.data : ajaxUrl;

        if (glob.isDebug && arrExt.indexOf(ext) === -1) {
            options.type = 'GET';
            if (options.url.indexOf('changyou.com') !== -1) {
                options.url = ajaxUrl + '.json';
            }else {
                options.url = glob.originOnly + ajaxUrl + '.json';
            }
            delete options.data;
        }

        if(glob.pendingRequests[keyName]) {
            jqXHR.abort();
        }else {
            if(glob.excludePort && glob.excludePort.indexOf(ajaxUrl) === -1) {
                glob.pendingRequests[keyName] = Date.now();
            }
        }

        options.complete = function(request, status) {
            if(status === 'success' && request.responseText) {

				// 区分 getScript 情况
                if(!utils.isJSON(request.responseText)) {
                    return false;
                }
                var code = request.responseText != 'null' ? Number(JSON.parse(request.responseText).code) : 0;
                switch (code) {
                    case 1012:case 1019:  // 登录异常、登录失效
                        var count = storage.getErrorCode()[ajaxUrl] || 0
                        storage.setErrorCode(ajaxUrl, ++count)
                        storage.removeLoginInfo()
                        if(storage.getErrorCode()[ajaxUrl] >= 5) {
                            message.error('接口：' + ajaxUrl + '，错误码：' + code)
                            storage.removeErrorCode(ajaxUrl)
                        }else {
                            utils.reload()
                        }
                        break;
                    default:
                        storage.removeErrorCode(ajaxUrl);
                        break;
                }
            }
            if(status === 'error') {
                if(request.status == 500) {
                    alert(request.status + '\n' + request.statusText)
                }
            }

            if(glob.pendingRequests[keyName]) {
                var timeDiff = Date.now() - glob.pendingRequests[keyName];
                var timeWait = 200;
                if(timeDiff > timeWait) {
                    glob.pendingRequests[keyName] = null;
                }else {
                    var timer = setTimeout(function() {
                        glob.pendingRequests[keyName] = null;
                        clearTimeout(timer);
                    }, timeWait - timeDiff);
                }
            }
        }
    });

    // bind IE8 兼容
    if(!Function.prototype.bind){
        Function.prototype.bind = function(oThis){
            if(typeof this !== 'function') {
                throw new TypeError('试图被绑定的东西是不可调用的')
            }
            var aArgs = Array.prototype.slice.call(arguments,1),
                fToBind = this,
                fNOP = function(){};
            var fBound = function(){
                return fToBind.apply(this instanceof fNOP ? this : oThis,
                    aArgs.concat(Array.prototype.slice.call(arguments)))
            };
            fNOP.prototype = this.prototype;
            fBound.prototype = new fNOP();
            return fBound;
        }
    }

    /**
     * == 中间件，用来管理初始化流程 ==
     **/
    var MidWare = function () {
        this.cache = [];
        this.options = {};
    };
    MidWare.prototype = {
        use: function (fn) {
            this.cache.push(fn);
            return this;
        },
        next: function () {
            if (this.cache && this.cache.length > 0) {
                var ware = this.cache.shift();
                ware.call(this, this.options || {}, this.next.bind(this));
            }
        },
        handleRequest: function (options) {
            this.options = options;
            this.next();
        }
    };

    /************************************* 工具类API方法 ***********************************/
    /**
     * == 工具 ==
     **/
    function Utils() {
    }
    Utils.prototype = {
        log: function(msg) {
            msg = glob.appName + ':' + msg
            try {
                logDebug.send(msg)
            }
            catch(err) {
                $.getScript('//www.changyou.com/cyouFile/loger/huodong.js', function() {
                    logDebug.send(msg)
                })
            }
        },
        /*
        * 获取地址中‘？’后面的值
        *   name 必填，要获取值的属性
        *   url 非必填，指定获取的路径
        * */
        getQueryString: function (name, url) {
            var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)'),
                search = decodeURIComponent((url && url.split('?')[1]) || window.location.search.substr(1)),
                r = search.match(reg);
            if (r != null) return r[2];
            return null;
        },
        /*
        * 获取地址中传递值的对象
        *   url 非必填，指定获取的路径
        * */
        getParams: function (url) {
            var url = url || location.href; //获取url中"?"符后的字串
            var theRequest = new Object();
            if (url.indexOf("?") != -1) {
                var str = url.split('?')[1];
                if(str) {
                    var strs = str.split("&");
                    for (var i = 0; i < strs.length; i++) {
                        var keyVal = strs[i].split("=");
                        theRequest[keyVal[0]] = decodeURIComponent(keyVal[1]);
                    }
                }

            }
            return theRequest;
        },
        // 判断某字符串是否是JSON格式
        isJSON: function (str) {
            if (typeof str == 'string') {
                try {
                    return typeof JSON.parse(str) == 'object';
                } catch (e) {
                    return false;
                }
            }
        },
        // 删除对象中值为undefined的键值对
        objDelUndefined: function (obj) {
            var json = {};
            for (var key in obj) {
                if (obj[key]) json[key] = obj[key];
            }
            return json;
        },
        // 删除 jcode
        deleteJcode: function(url) {
            url = url || location.href
            var urlMain = url.split('?')[0],
                urlParamsObj = this.getParams(url),
                paramsStr = ''
            delete urlParamsObj.jcode
            if(!$.isEmptyObject(urlParamsObj)) {
                paramsStr = '?' + $.param(urlParamsObj)
            }
            return urlMain + paramsStr
        },
        // 删除 地址栏参数
        deleteUrlParam: function(name) {
            var url = location.href,
                urlMain = url.split('?')[0],
                urlParamsObj = this.getParams(url),
                paramsStr = ''
            delete urlParamsObj[name]
            if(!$.isEmptyObject(urlParamsObj)) {
                paramsStr = '?' + $.param(urlParamsObj)
            }
            return urlMain + paramsStr
        },
        // 回到顶部
        backTop: function (num, time) {
            $('html, body').animate({scrollTop: (num || 0) + 'px'}, time || 300);
        },
        // 单数变双数
        getTwo: function (n) {
            n = n.toString();
            return n[1] ? n : "0" + n;
        },
        // 格式化 日期
        formatDate: function (now) {
            now = now ? new Date(now) : new Date();
            var year = now.getFullYear();
            var month = now.getMonth() + 1;
            var date = now.getDate();
            return year + "-" + this.getTwo(month) + "-" + this.getTwo(date);
        },
        // 格式化 日期+时间
        formatDateTime: function (now) {
            now = now ? new Date(now) : new Date();
            var year = now.getFullYear();
            var month = now.getMonth() + 1;
            var date = now.getDate();
            var hour = now.getHours();
            var minute = now.getMinutes();
            var second = now.getSeconds();
            return year + "-" + this.getTwo(month) + "-" + this.getTwo(date) + " " + this.getTwo(hour) + ":" + this.getTwo(minute) + ":" + this.getTwo(second);
        },
        urlAddKey: function (url, key, val) {
            key = (key || 't') + '=';  //默认是"t"
            url = url || location.href;
            var reg = new RegExp(key + '\\d+');  //正则：t=1472286066028
            var timestamp = val || +new Date();
            if (url.indexOf(key) > -1) { //有时间戳，直接更新
                return url.replace(reg, key + timestamp);
            } else {  //没有时间戳，加上时间戳
                if (url.indexOf('\?') > -1) {
                    var urlArr = url.split('\?');
                    if (urlArr[1]) {
                        return urlArr[0] + '?' + key + timestamp + '&' + urlArr[1];
                    } else {
                        return urlArr[0] + '?' + key + timestamp;
                    }
                } else {
                    if (url.indexOf('#') > -1) {
                        return url.split('#')[0] + '?' + key + timestamp + location.hash;
                    } else {
                        return url + '?' + key + timestamp;
                    }
                }
            }
        },
        href: function (url) {
            if(isIos) {
                location.href = url;
            }else {
                location.replace(url);
            }
        },
        reload: function () {
            var newUrl = location.href.replace(location.hash, '');
            location.href = this.deleteJcode(newUrl)
        },
        // 对象深层合并
        deepMerge: function (obj1, obj2) {
            for (var key in obj2) {
                obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" ?
                    utils.deepMerge(obj1[key], obj2[key]) : obj1[key] = obj2[key];
            }
            return obj1;
        },
        timeToDate: function(time) {
            if(time > 2 * 60 * 60 * 1000) {
                return '已过期'
            }
            var s = parseInt(time / 1000)
            var m = parseInt(s / 60)
            var h = parseInt(m / 60)
            var arr = [s % 60 + '秒']
            if(m > 0) {
                arr.unshift(m % 60 + '分钟')
            }
            if(h > 0) {
                arr.unshift(h % 60 + '小时')
            }
            return arr.join('')
        },
        landscape: function(config) {
            if (isMobile) {
                var isVertical = '1';
                var showWay = isVertical ? "@media screen and (min-aspect-ratio: 12/7){#orientLayer{display:block;} }" :
                    "@media all and (orientation : portrait){#orientLayer{display: block;} }";
                var color = config && config.color ? config.color : "#000",
                    txt = isVertical ? "为了更好的体验，请使用竖屏浏览" : "为了更好的体验，请使用横屏浏览",
                    images = config && config.images ? config.images :
                        "https://i0.cy.com/cy/public/landscape.png";
                // style
                var nodeStyle = document.createElement('style');
                nodeStyle.setAttribute('type', 'text/css');
                nodeStyle.innerHTML =
                    '@-webkit-keyframes rotation{10%{transform: rotate(90deg); -webkit-transform: rotate(90deg)} 50%, 60%{transform: rotate(0deg); -webkit-transform: rotate(0deg)} 90%{transform: rotate(90deg); -webkit-transform: rotate(90deg)} 100%{transform: rotate(90deg); -webkit-transform: rotate(90deg)} } @keyframes rotation{10%{transform: rotate(90deg); -webkit-transform: rotate(90deg)} 50%, 60%{transform: rotate(0deg); -webkit-transform: rotate(0deg)} 90%{transform: rotate(90deg); -webkit-transform: rotate(90deg)} 100%{transform: rotate(90deg); -webkit-transform: rotate(90deg)} } #orientLayer{display: none; z-index: 999999;} ' +
                    showWay +
                    ' .mod-orient-layer{display: none; position: fixed; height: 100%; width: 100%; left: 0; top: 0; right: 0; bottom: 0; background: ' +
                    color +
                    '; z-index: 9997} .mod-orient-layer__content{position: absolute; width: 100%; top: 45%; margin-top: -75px; text-align: center} .mod-orient-layer__icon-orient{background-image: url(' +
                    images +
                    '); display: inline-block; width: 67px; height: 100px; transform: rotate(90deg); -webkit-transform: rotate(90deg); -webkit-animation: rotation infinite 1.5s ease-in-out; animation: rotation infinite 1.5s ease-in-out; -webkit-background-size: 67px; background-size: 67px} .mod-orient-layer__desc{margin-top: 20px; font-size: 15px; color: #fff}'
                document.getElementsByTagName('body')[0].appendChild(nodeStyle);
                // dom
                var nodeDom = document.createElement('div');
                nodeDom.setAttribute('id', 'orientLayer');
                nodeDom.setAttribute('class', 'mod-orient-layer');
                nodeDom.innerHTML =
                    '<div class="mod-orient-layer__content"> <i class="icon mod-orient-layer__icon-orient"></i> <div class="mod-orient-layer__desc">' +
                    txt + '</div> </div>';
                document.getElementsByTagName('body')[0].appendChild(nodeDom);
            }
        },
        // 判断IE浏览器的具体版本
        IEVersion: function() {
            var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
            var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
            var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器
            var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1;
            if(isIE) {
                var reIE = new RegExp("MSIE (\\d+\\.\\d+);");
                reIE.test(userAgent);
                var fIEVersion = parseFloat(RegExp["$1"]);
                if(fIEVersion == 7) {
                    return 7;
                } else if(fIEVersion == 8) {
                    return 8;
                } else if(fIEVersion == 9) {
                    return 9;
                } else if(fIEVersion == 10) {
                    return 10;
                } else {
                    return 6;//IE版本<=7
                }
            } else if(isEdge) {
                return 'edge';//edge
            } else if(isIE11) {
                return 11; //IE11
            }else{
                return -1;//不是ie浏览器
            }
        },
        // 获取 function 函数名
        getFunName: function(fun) {
            var matches = fun.toString().match(/function\s*(\w*)/i);
            return matches[1];
        },
        vconsole: function(fn) {
            $.getScript(staticOrigin + '/act/all/cdn/join-activity/2.6/lib/vconsole.min.js', function() {
                var vConsole = new VConsole();
                fn && fn()
            })
        },
        excelToJson: function(url, callback) {
            var json = {};
            $.getScript(staticOrigin + '/act/all/cdn/join-activity/2.6/lib/xlsx.core.min.js', function() {
                var xhr = createXhr();
                xhr.open('get', url, true);
                xhr.responseType = 'arraybuffer';
                xhr.onload = function (e) {
                    if (xhr.status == 200) {
                        var data = new Uint8Array(xhr.response);
                        var wb = XLSX.read(data, { type: 'array' });
                        var sheetNameList = wb.SheetNames;
                        if(sheetNameList.length > 1) {
                            json = {};
                            for(var i = 0; i < sheetNameList.length; i++) {
                                json[sheetNameList[i]] = XLSX.utils.sheet_to_json(wb.Sheets[sheetNameList[i]])
                            }
                        }else {
                            json = XLSX.utils.sheet_to_json(wb.Sheets[sheetNameList[0]]);
                        }
                        callback && callback(json);
                    }
                };
                xhr.send();
            });
        },
        // 手机号版本
        phoneVersion: function() {
            if(!isMobile) return false;

            var modelV = '';
            var dtd = $.Deferred(); // 生成Deferred对象
            $.getScript(staticOrigin + '/act/all/cdn/join-activity/2.6/lib/mobile-detect.min.js', function() {
                Array.prototype.contains = function(needle) {
                    for (i in this) {
                        if (this[i].indexOf(needle) > 0)
                            return i;
                    }
                    return -1;
                };
                var device_type = navigator.userAgent;
                var md = new MobileDetect(device_type);
                var os = md.os(); // 获取系统
                var model = "";
                if (os == "iOS") { //ios系统的处理
                    os = md.os() + md.version("iPhone");
                    model = md.mobile();
                    // model = iphone();
                } else if (os == "AndroidOS") { //Android系统的处理
                    os = md.os() + md.version("Android");
                    var sss = device_type.split(";");
                    var i = sss.contains("Build/");
                    if (i > -1) {
                        model = sss[i].substring(0, sss[i].indexOf("Build/"));
                    }
                }
                modelV = model + '-' + os;
                dtd.resolve(modelV);
            });

            return dtd;
        },
        /**
         * @desc 函数节流
         * @param func 函数
         * @param wait 延迟执行毫秒数
         * @param type 1 表时间戳版(立即执行)，2 表定时器版(非立即执行)
         */
        throttle: function(func, wait ,type) {
            if(type===2){
                var timeout;
            }else {
                var previous = 0;
            }
            return function() {
                var context = this;
                var args = arguments;
                if(type===2){
                    if (!timeout) {
                        timeout = setTimeout(function() {
                            timeout = null;
                            func.apply(context, args)
                        }, wait)
                    }
                }else {
                    var now = Date.now();
                    if (now - previous > wait) {
                        func.apply(context, args);
                        previous = now;
                    }
                }
            }
        },
        /**
         * @desc 函数防抖
         * @param func 函数
         * @param wait 延迟执行毫秒数
         * @param immediate true 表立即执行，false 表非立即执行
         */
        debounce: function(func,wait,immediate) {
            var timeout;
            return function () {
                var context = this;
                var args = arguments;
                if (timeout) clearTimeout(timeout);
                if (immediate) {
                    var callNow = !timeout;
                    timeout = setTimeout(function() {
                        timeout = null;
                    }, wait);
                    if (callNow) func.apply(context, args)
                }
                else {
                    timeout = setTimeout(function(){
                        func.apply(context, args)
                    }, wait);
                }
            }
        },
        // 弹窗
        win: {
            // 打开
            open: function (width, height, src) {
                var iframeHeight = height;
                var marginLeft = width / 2;
                var marginTop = height / 2;
                var inntHtml = '';
                inntHtml += '<div id="mask" style="width:100%; height:100%; position:fixed; top:0; left:0; z-index:1999;background:#cccccc; filter:alpha(opacity=50); -moz-opacity:0.5; -khtml-opacity: 0.5; opacity:0.5;"></div>';
                inntHtml += '<div id="maskTop" style="width: ' + width + 'px; height: ' + height + 'px;  color: #333; position: fixed; top: 50%; left: 50%; margin-left: -' + marginLeft + 'px; margin-top: -' + marginTop + 'px; z-index: 2999; ">';
                inntHtml += '<div id="maskTitle" style="height: 0;position: relative;">';
                inntHtml += '<div id="winClose" style="width: 28px; height: 28px; cursor: pointer; position: absolute; top: -12px; right: -9px; z-index: 1;background-image: url();"></div>';
                inntHtml += '</div>';
                inntHtml += '<iframe width="' + width + '" height="' + iframeHeight + '" frameborder="0" scrolling="no" src="' + src + '"></iframe>';
                inntHtml += '</div>';
                $("body").append(inntHtml);

                $("#winClose")
                    .mouseenter(function () {
                        $(this).css("background-image", "url()");
                    })
                    .mouseleave( function () {
                        $(this).css("background-image", "url()");
                    })
                    .click(this.close);
            },
            // 关闭
            close: function () {
                $("#mask, #maskTop").fadeOut(function () {
                    $(this).remove();
                });
            }
        },
        // 存储cookie
        cookie: {
            get: function (cname) {
                var name = cname + '=';
                var ca = document.cookie.split(';');
                for (var i = 0; i < ca.length; i++) {
                    var c = ca[i];
                    while (c.charAt(0) == ' ') c = c.substring(1);
                    if (c.indexOf(name) != -1) return c.substring(name.length, c.length);
                }
                return '';
            },
            set: function (cname, cvalue, exdays, domain) {
                var d = new Date();
                d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
                var expires = 'expires=' + d.toUTCString();
                document.cookie = cname + '=' + cvalue + '; ' + expires + '; domain=' + domain + '; path=/';
            },
            del: function (name, domain) {
                this.set(name, '', -1, domain);
            }
        },
        // 存储sessionStorage，自动转换对象存储和获取
        session: {
            set: function (name, value) {
                if (Object.prototype.toString.call(value) === '[object Object]') value = JSON.stringify(value);
                sessionStorage.setItem(name, value)
            },
            get: function (name) {
                var value = sessionStorage.getItem(name);
                return utils.isJSON(value) ? JSON.parse(value) : value;
            }
        },
        isLocalStorageEnabled: function() {
            try {
                localStorage.setItem('name', 'Hello World!')
                sessionStorage.setItem('name', 'Hello World!')
                localStorage.removeItem('name')
                sessionStorage.removeItem('name')
            } catch (e) {
                alert('检测到您的本地存储功能禁用，请开启后体验完整功能')
            }
        }
    };
    var utils = new Utils();
    /**
     * == 弹窗 ==
     **/
    function Dialog() {
    }
    Dialog.prototype = {
        isExist: function (elem) {
            if (typeof elem !== 'undefined' && typeof elem !== null) {
                return true;
            } else {
                return false;
            }
        },
        preventDefaultTouchMove: function(e) {
            e.preventDefault()
        },
        removeOverlay: function () {
            if (document.getElementById('Overlay')) {
                document.getElementById('Overlay').removeEventListener('touchmove', this.preventDefaultTouchMove)
                $('#Overlay').remove();
            }
        },
        addOverlay: function (cl, op, zIndex) {
            var _this = this
            this.removeOverlay();
            var overlayCss = {
                position: 'fixed',
                zIndex: zIndex,
                top: '0px',
                left: '0px',
                height: '100%',
                width: '100%',
                backgroundColor: '#000',
                filter: 'alpha(opacity=60)',
                opacity: 0.6
            }
            var overlay = $('<div id="Overlay" class="OverlayBG" />');

            if (this.isExist(cl)) overlayCss.backgroundColor = cl;
            $('body').append(overlay.css(overlayCss));
            if (this.isExist(op)) {
                $('#Overlay').animate({opacity: op}, 0);
            }
            setTimeout(function() {
                if(document.getElementById('Overlay')) {
                    document.getElementById('Overlay').addEventListener('touchmove', _this.preventDefaultTouchMove)
                }
            }, 1000)
        },
        toggleBody: function (isPin) {
            if (isPin) {
                document.body.style.height = '100vh';
                document.body.style['overflow-y'] = 'hidden'
            } else {
                document.body.style.height = '';
                document.body.style['overflow-y'] = 'auto'
            }
        },
        popup: function (target, zIndex) {
            zIndex = zIndex || 9999
            var _this = this;
            this.toggleBody(1);
            this.addOverlay('#000', 0.75, zIndex - 1);
            if(typeof target === 'string') {
                target = $(target);
            }
            target.css("position", "fixed")
                .css("top", ($(window).height() - target.outerHeight()) / 2)
                .css("left", ($(window).width() - target.outerWidth()) / 2)
                .css("z-index", zIndex)
                .show();
            $(".pop_close, .dialog_close", target).click(function () {
                _this.hideMask(target);
                return false;
            });
            target[0].addEventListener('touchmove', this.preventDefaultTouchMove)
        },
        hideMask: function (target) {
            this.toggleBody(0);
            this.removeOverlay();
            if (target) {
                target.hide();
            } else {
                $('.ja_login_box').fadeOut();
            }
            return false;
        },
        tips: function(msg) {
            if(timerTips) {
                clearTimeout(timerTips)
            }
            if($('#JaPopTip').length) {
                $('#JaPopTip p').html(msg)
            }else {
                var tipsHtml = '<div style="height: 100vh; display: none; text-align: center; position: fixed; top: 0;left: 0; right: 0; z-index:99999; display: flex; justify-content: center; align-items: center;" id="JaPopTip"><p style="max-width: 90%; max-height: 50px; border-radius: 10px;color: #fff;font-size: 30px;background: rgba(0, 0, 0, .8);padding: 15px 15px 15px 20px;">' + msg + '</p></div>'
                $('body').append(tipsHtml)
            }
            $('#JaPopTip').show()
            timerTips = setTimeout(function() {
                $('#JaPopTip').hide()
            }, 3000)
            $('#JaPopTip').click(function() {
                $('#JaPopTip').hide()
            })
        }
    };
    var dialog = new Dialog();
    /**
     * == 提示 ==
     **/
    function Message() {
    }
    Message.prototype = {
        self: function (opt) {
            var _opt = {
                name: '',
                nStyle: {color: '#fff', background: '#606060'},
                value: 'value',
                vStyle: {color: '#fff', background: '#42C02E'}
            };
            utils.deepMerge(_opt, opt);
            if(utils.IEVersion() === -1) {
                console.log('%c ' + _opt.name + ' %c ' + _opt.value,
                    'color:' + _opt.nStyle.color + ';background:' + _opt.nStyle.background + ';border-radius: 3px 0 0 3px',
                    'color:' + _opt.vStyle.color + ';background:' + _opt.vStyle.background + ';padding-right: 5px;border-radius: 0 3px 3px 0')
            }else {
                console.log(_opt.name + ':', _opt.value)
            }
        },
        console: function (name, msg) {
            var _opt = {
                name: name,
                value: msg
            };
            this.self(_opt);
        },
        warning: function (msg) {
            if(_glob.env === 'prod') return
            var _opt = {
                name: 'warning',
                nStyle: {color: '#fff'},
                value: msg,
                vStyle: {background: '#ffae47'}
            };
            this.self(_opt);
        },
        error: function (msg) {
            var _opt = {
                name: 'error',
                nStyle: {color: '#fff'},
                value: msg,
                vStyle: {background: '#f00'}
            };
            this.self(_opt)
        },
    };
    var message = new Message();
    /**
     * == 表单验证 ==
     **/
    function Verify() {}
    Verify.prototype = {
        reg: {
            phone: /^1[3456789]\d{9}$/,
            email: /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/,           // 邮箱
            username: /^[a-z0-9_-]{3,16}$/,                     // 用户名
            chineseName: /^[\u4E00-\u9FA5]{2,4}$/,              // 中文姓名
        },
        // 手机号
        phone: function (val) {
            val = val.toString();
            if (!val) {
                return '请填写手机号！';
            } else if (!val.match(this.reg.phone)) {
                return '请输入正确的手机号！';
            } else {
                return false;
            }
        },
        // 验证码
        phoneCode: function (val) {
            if (!val) {
                return '请填写验证码！';
            } else if (val.length !== 6) {
                return '验证码错误！'
            } else {
                return false;
            }
        }
    };
    var verify = new Verify();
    /**
     * == 本地存储值统一管理 ==
     **/
    function Storage() {
    }
    Storage.prototype = {
        // 微信授权前（刷新前）标识，用来刷新后执行下一步操作
        setWechatSign: function () {
            sessionStorage.setItem(glob.appName + ':wechatSign', 1)
        },
        getWechatSign: function () {
            return sessionStorage.getItem(glob.appName + ':wechatSign')
        },
        removeWechatSign: function () {
            sessionStorage.removeItem(glob.appName + ':wechatSign')
        },
        // 地址栏参数存储（微信授权前，避免丢参）
        setStrParams: function (val) {
            utils.session.set(glob.appName + ':params', val)
        },
        getStrParams: function () {
            return utils.session.get(glob.appName + ':params')
        },
        removeStrParams: function () {
            sessionStorage.removeItem(glob.appName + ':params')
        },
        // 时间戳
        setTimestamp: function (val) {
            utils.session.set(glob.appName + ':timestamp', val || Date.now())
        },
        getTimestamp: function () {
            return utils.session.get(glob.appName + ':timestamp')
        },
        removeTimestamp: function () {
            sessionStorage.removeItem(glob.appName + ':timestamp')
        },
        // 错误码
        setErrorCode: function (key, val) {
            var obj = this.getErrorCode();
            obj[key] = val;
            utils.session.set(glob.appName + ':errorCode', obj)
        },
        getErrorCode: function () {
            return utils.session.get(glob.appName + ':errorCode') || {}
        },
        removeErrorCode: function (key) {
            if(key) {
                var obj = this.getErrorCode();
                delete obj[key];
                glob.appName && utils.session.set(glob.appName + ':errorCode', obj)
            }else {
                sessionStorage.removeItem(glob.appName + ':errorCode')
            }
        },
        // 登录类型（wegame/changyou）
        setLoginType: function(val) {
            localStorage.setItem(glob.platform + ':loginType', val)
        },
        getLoginType: function() {
            return localStorage.getItem(glob.platform + ':loginType')
        },
        removeLoginType: function() {
            localStorage.removeItem(glob.platform + ':loginType')
        },
        // 微信用户信息
        setWechatInfo: function(obj) {
            localStorage.setItem('wechatInfo', JSON.stringify(obj))
        },
        getWechatInfo: function() {
            return JSON.parse(localStorage.getItem('wechatInfo'))
        },
        removeWechatInfo: function() {
            localStorage.removeItem('wechatInfo')
        },
        // 用户信息（长期）
        setLUserInfo: function(obj) {
            var userInfo = this.getLUserInfo() || {}
            obj = $.extend(userInfo, obj)
            localStorage.setItem('userInfo', JSON.stringify(obj))
        },
        getLUserInfo: function() {
            return JSON.parse(localStorage.getItem('userInfo')) || {}
        },
        removeUserInfo: function() {
            localStorage.removeItem('userInfo')
        },

        // 注销/登录状态失效，同步本地存储信息
        removeLoginInfo: function() {
            this.removeLoginType()
            this.removeWechatInfo()
            this.removeUserInfo()
            if (['changyou', 'warframe', 'wechat', 'changyouwg'].indexOf(glob.platform) !== -1) {
                utils.cookie.del('CASGTC', '.changyou.com');
            }
        }
    };
    var storage = new Storage();

    /************************************* 业务类API方法 ***********************************/
    /**
     * == 用户业务 ==
     **/
    function User() {
    }
    User.prototype = {
        // 获取token
        getToken: function (fun) {
            $.ajax({
                url: glob.originAll + '/landing/init',
                async: glob.async,
                success: function (res) {
                    if (res.code === 10000) {
                        var item = res.data;
                        if (!item.token) {
                            message.error('无token，请联系后台开发添加');
                        }
                        if (!item.activity) {
                            message.error('无活动信息，请联系后台开发添加');
                        }
                    }else {
                        if(glob.v === '2.1') {
                            var obj = {
                                1106: 2,
                                1103: 3,
                                1102: 5
                            };
                            glob.code = obj[res.code];
                        }
                    }
                    fun && fun(res)
                }
            })
        },
        // 登录
        login: function (info) {
            info = info || {};
            info = info.target
                ? typeof info.data === 'string' ? {plat: info.data} : info.data || {}
                : typeof info === 'string' ? {plat: info} : info;

            if(info.isCustom && glob.loginMethod) {
                return glob.loginMethod();
            }

            var globCode = _glob.code;

            if(globCode === 10000) {
                var plat = info.plat || glob.platform,
                    url = glob.originOnly + '/' + plat + glob.pathCore
                        + (info.w2c ? '/w2c' : '') +'?callback=' + encodeURI(utils.deleteJcode(location.href));
                if(info.gameType) {
                    url += '&gameType=' + info.gameType
                }
                if(info.isUrl) {
                    return url
                }
                // 登陆前，清除登录标识
                utils.cookie.del('CASGTC', '.changyou.com');
                // 清除原弹窗
                dialog.hideMask();
                // 如果 plat 不是 wechat、wechat1，但需要授权，先授权
                // if(plat.indexOf('wechat') === -1 && glob.isWxLogin && !_glob.isWLogin) {
                //     this.login('wechat')
                //     return
                // }
                switch (plat) {
                    case 'warframe':
                    case 'changyouwg':  // 星际战甲、海战世界
                        utils.win.open(496, 360, url);
                        break;
                    case 'wegame':       // wegame平台
                        window.location.href = url;
                        break;
                    case 'wgchangyou':   // 畅游wegame二选一
                        storage.setLoginType(info.w2c ? 'C' : 'W')

                        if(!info.w2c) {
                            window.location.href = url;
                            break;
                        }
                    case 'changyou':     // 畅游平台
                        if (isMobile) {
                            if (glob.isForceMobileLogin || info.m === 1) {
                                var width = document.documentElement.clientWidth;
                                if(width >=1000) {
                                    utils.win.open(1000, 1600, url);
                                }else if (width >= 800) {
                                    utils.win.open(800, 1200, url);
                                } else if(width >= 600) {
                                    utils.win.open(570, 1000, url);
                                } else {
                                    utils.win.open(320, 550, url);
                                }
                                if(isMobile && isIos) {
                                    // 监听键盘打开收起，修复IOS12系统引起的点击错位
                                    window.onmessage = utils.debounce(function(event) {
                                        event.data.isReset && utils.backTop();
                                    }, 300, false);
                                }
                            } else
                                window.location.href = url
                        } else {
                            if (glob.isForceMobileLogin || info.pc === 1)
                                utils.win.open(320, 550, url);
                            else
                                utils.win.open(496, 360, url);
                        }
                        break;
                    case 'cyou3':       // 橙柚
                        url += '&' + $.param({
                            from: info.from,
                            type: info.type
                        });
                        isMobile ? window.location.href = url : utils.win.open(490, 470, url);
                        break;
                    case 'wechat':      // 微信
                        glob.isWechatLogin = true;
                        if(isWechat) {
                            if(glob.wxTips) {
                                dialog.tips(
                                    typeof glob.wxTips === 'string' ? wxTips : '正在获取授权，请在页面刷新完成后重新操作！'
                                )
                            }
                            if(!glob.isAutoWxLogin) {
                                storage.setWechatSign()
                            }
                            window.location.href = url;
                        }
                        break;
                    case 'wechat1':      // 微信（静默授权）
                        glob.isWechatLogin = true
                        var authUrl = glob.originOnly + '/wechat/core/login/auth/' +
                                        glob.app + '/' + glob.activity + '/' + glob.version +
                                        '/1?callback=' + encodeURI(utils.deleteJcode(location.href));
                        if(isWechat) window.location.href = authUrl;
                        break;
                    case 'dj':
                        try {
                            djLogin();
                            message.warning('这里使用的是dj旧版登录方式')
                        }catch (e) {
                            message.warning('这里使用的是dj新版登录方式，如需使用旧版，可参照活动:/dj/goddess/20200509/pc/index.shtml')
                            this.dlogin(info.scale);
                        }
                        break;
                    case 'changyou-xtl':
                        info.plat = info.platSub;
                        this.tlogin(info);
                        break;
                    case 'phone':
                        this.plogin(info); break;
                    //轻松天龙登录对应弹出框
                    case 'qstl':
                        if (isMobile) {
                            if (glob.isForceMobileLogin || info.m === 1) {
                                window.location.href = url
                            } else{
                                var width = document.documentElement.clientWidth;
                                if(width >=1000) {
                                    utils.win.open(1000, 1030, url);
                                }else if (width >= 800) {
                                    utils.win.open(800, 824, url);
                                } else if(width >= 600) {
                                    utils.win.open(570, 587, url);
                                } else {
                                    utils.win.open(320, 330, url);
                                }
                                if(isMobile && isIos) {
                                    // 监听键盘打开收起，修复IOS12系统引起的点击错位
                                    window.onmessage = utils.debounce(function(event) {
                                        event.data.isReset && utils.backTop();
                                    }, 300, false);
                                }
                            }
                        } else {
                            if (glob.isForceMobileLogin || info.pc === 1)
                                utils.win.open(320, 330, url);
                            else
                                utils.win.open(496, 510, url);
                        }
                        break;
                    default:
                        alert('暂时还没有该平台登陆功能');
                }
            }else {
                glob.isAlert && glob.msg[globCode] && alert(glob.msg[globCode]);
            }
        },
        // 退出/注销
        logout: function (url) {
            url = typeof url === 'string' ? url : location.href
            function logoutAct() {
                $.ajax({
                    type: 'POST',
                    url: glob.originAll + glob.pathCore + '/logout',
                    success: function () {
                        storage.removeLoginInfo()
                        //直接注销，不考虑chong.changyou.com,不丢参
                        if(glob.platform === 'qstl'){
                            location.href = 'https://chong.changyou.com/common/preLogout.do?s=' + encodeURIComponent(encodeURIComponent(url));
                            //location.href = 'https://auth.changyou.com/logout?b=' + encodeURIComponent(url);
                        }else{
                            location.href = 'https://chong.changyou.com/common/preLogout.do?s=' + url;
                        }
                    }
                });
            }

            if (isWechat && (glob.isWxLogin || glob.platform === 'wechat')) {   // 微信平台退出
                $.ajax({
                    type: 'POST',
                    url: glob.originOnly + '/wechat/auto/cancel',
                    headers: {'PLAT': 'wechat'},
                    success: function (res) {
                        if (res.code === 10000 || res.code == 1012) {
                            logoutAct();
                        }else {
                            alert(res.message)
                        }
                    }
                });
            } else {
                logoutAct();
            }
        },
        // 获取用户信息
        getUserInfo: function (plat) {
            plat = plat || glob.platform;
            var resInfo = undefined;
            $.ajax({
                url: glob.originOnly + '/' + plat + '/user/info',
                async: false,
                headers: {'PLAT': plat},
                success: function (res) {
                    if (res.code === 10000) {
                        resInfo = res.data;
                    } else {
                        resInfo = undefined;
                    }
                }
            });
            return resInfo;
        },
        // 获取验证码
        getCode: function (phone) {
            var info,
                codeInit = 60,
                styleSheet = glob.style,
                $btnPhoneCode = $(glob.ele.btnPhoneCode),
                styleBefore = styleSheet.beforeCode,     // 默认样式，可点击
                styleAfter = styleSheet.afterCode,   // 请求过程中、或倒计时中，不可点击
                errMsg = verify.phone(phone),
                btnValue = $btnPhoneCode.text();    // 获取 发送验证码按钮 原内容

            if (errMsg) return alert(errMsg);

            $btnPhoneCode.html('发送中...').css(styleAfter);

            $.ajax({
                type: 'POST',
                url: glob.originOnly + '/phone/core/zhpt/sendcode',
                async: false,
                data: {phone: phone},
                success: function (res) {
                    info = res;
                    if (res.code === 10000) {
                        $btnPhoneCode.css(styleAfter);
                        var codeNum = codeInit,
                            timer = setInterval(function () {
                                $btnPhoneCode.text(codeNum + 's');
                                if (codeNum <= 0) {
                                    $btnPhoneCode.text(btnValue).css(styleBefore);
                                    clearInterval(timer);
                                }
                                codeNum--;
                            }, 1000)
                    } else {
                        $btnPhoneCode.text(btnValue).css(styleBefore);
                        alert(res.message);
                    }
                },
                error: function() {
                    alert('接口异常')
                }
            });

            return info;
        },
        // 手机号与验证码登陆
        loginPhone: function (phone, code) {
            var info,
                styleSheet = glob.style,
                $btnPhone = $(glob.ele.btnPhone),
                btnValue = $btnPhone.text(),
                styleBefore = styleSheet.beforePhone,     // 默认样式，可点击
                styleAfter = styleSheet.afterPhone,   // 请求过程中、或倒计时中，不可点击
                errorPhone = verify.phone(phone),
                errorPhoneCode = verify.phoneCode(code);

            if (errorPhone) return alert(errorPhone);

            if (errorPhoneCode) return alert(errorPhoneCode);

            $btnPhone.text('登录中...').css(styleAfter);

            $.ajax({
                type: 'POST',
                url: glob.originOnly + '/phone' + glob.pathCore + '/phonelogin',
                async: false,
                data: {phone: phone, code: code},
                headers: {'PLAT': 'phone'},
                success: function (res) {
                    info = res;
                    if (res.code === 10000) {
                        $btnPhone.text(btnValue).css(styleBefore);
                    } else {
                        $btnPhone.text(btnValue).css(styleBefore);
                        alert(res.message);
                    }
                }
            });

            return info;
        },
        // 二选一登录弹窗（天龙）
        tlogin: function (info) {
            info = (info && info.target ? info.data : info) || {};
            if (isMobile && isWechat) {
                if (!glob.isWxStatus && !_glob.wxBindName) {
                    _glob.wxBindName = wechat.wxStatus().data;
                }
                var isBind = !!_glob.wxBindName;
                var imgBase = imgHost + '/xtl/main/20200513/';
                if ($('.login_or_wrapper').length === 0) {
                    var css = {
                        bg: 'background: url(' + imgBase + 'login_or_bg.png) no-repeat center center;' +
                            'width: 320px;height: 280px;' +
                            'background-size: 100% auto; position: relation;',
                        title: 'text-align: center;margin: 0;margin-top: 36px;' +
                            'font-size: 20px; height: 26px; font-weight: normal;',
                        subTitle: 'color: #a64e39; font-size: 16px; margin: 16px 0; height: 21px;',
                        box: 'display: flex;justify-content: center; ' +
                            'text-align: center;width: 93%;margin: 0 auto;',
                        wrap: 'width: 50%;',
                        imgWrap: 'display: block;width: 70px;height: 70px;' +
                            'margin: 28px auto 10px;',
                        wx: 'background: url(' + imgBase + 'wechat.png) no-repeat center center;',
                        wxbtn: 'width: 100px; color: #fff; font-size: 12px;' +
                            'background: #DF6738;' +
                            'text-decoration: none; padding: 5px 0; margin: 20px auto 0;' +
                            'border-radius: 5px; display:' + (isBind ? "none" : "block") + ';',
                        wxAccount: 'color: gray; font-size: 12px; text-decoration:none;' +
                            'display:' + (isBind ? "block" : "none") + ';',
                        cy: 'background: url(' + imgBase + 'changyou.png) no-repeat center center;',
                        cyBtn: 'font-size: 12px; color: #565344; line-height: 12px;' +
                            'text-decoration: none; padding: 0 5px;',
                        close: 'width: 30px; height: 30px; position: absolute; top: 0px; right: -10px;' +
                            'background: url(' + imgBase + 'close.png) no-repeat center center;' +
                            'background-size: 100% 100%;',
                    };
                    var html = '<div class="login_or_wrapper ja_login_box" style="' + css.bg + '">' +
                        '<h3 style="' + css.title + '">请选择登录方式</h3>' +
                        '<div style="' + css.box + '">' +
                        '<div style="' + css.wrap + '">' +
                        '<p style="' + css.subTitle + '">已绑定微信入口</p>' +
                        '<a href="javascript:;" onclick="ja.wxAutoLogin(' + (!isBind && 1) + ')" style="' + css.imgWrap + css.wx + '"></a>' +
                        '<a href="' + urlWxBind + '" style="' + css.wxbtn + '">点击前往绑定</a>' +
                        '<a href="javascript:;" style="' + css.wxAccount + '">' + _glob.wxBindName + '<br/>已绑定</a>' +
                        '</div>' +
                        '<div style="' + css.wrap + '">' +
                        '<p style="' + css.subTitle + '">未绑定微信入口</p>' +
                        '<a href="javascript:;" onclick="ja.login(' + JSON.stringify(info).replace(/"/g, '&quot;') + ')" style="' + css.imgWrap + css.cy + '"></a>' +
                        '<a href="javascript:;" style="' + css.cyBtn + '">未在微信绑定过畅游帐号的玩家可在此登录</a>' +
                        '</div>' +
                        '</div>' +
                        '<div class="login_or_close" onclick="ja.hideMask($(this).parent())" style="' + css.close + '"></div>' +
                        '</div>';
                    $('body').append(html);
                }
                dialog.popup($('.login_or_wrapper'));
            } else {
                user.login(info);
            }
        },
        // 手机号登录
        plogin: function (info) {
            function htmlCreate() {
                var html = '<div class="login_phone_wrapper ja_login_box">' +
                    '<h3 class="plogin_title">手机号登录</h3>' +
                    '<ul class="plogin_list">' +
                    '<li><input type="text" maxlength="11" class="plogin_phone" placeholder="输入手机号"/></li>' +
                    '<li>' +
                    '<input type="text" maxlength="6" class="plogin_phone_code" placeholder="验证码"/>' +
                    '<a href="javascript:;" class=" btn plogin_btn_phone_code">获取验证码</a>' +
                    '</li>' +
                    '<li><a href="javascript:;" class=" btn plogin_btn_phone">登 录</a></li>' +
                    '</ul>' +
                    '<a href="javascript:;" class="plogin_close" onclick="ja.hideMask($(this).parent())"></a>' +
                    '</div>';
                $('body').append(html);
            }
            function cssCreate() {
                $('.login_phone_wrapper').css({
                    width: 320, height: 240,
                    position: 'relation',
                    background: '#fff',
                    borderRadius: '8px'
                });
                $('.login_phone_wrapper *').css({ boxSizing: 'border-box' });
                $('.login_phone_wrapper .btn').css({
                    background: '#F8F8F8',
                    textDecoration: 'none',
                    padding: '2px 10px',
                    borderRadius: 5,
                    border: '1px solid #ccc',
                    display: 'inline-block',
                    height: 38,
                    lineHeight: '32px',
                    color: '#000'
                });
                $('.plogin_list').css({ paddingLeft: 10 });
                $('.plogin_list>li').css({ margin: '0 0 10px 10px',  overflow: 'hidden' });
                $('.plogin_title').css({
                    textAlign: 'center',
                    margin: '20px 0 20px 0',
                    fontSize: 24,
                    fontWeight: 'normal'
                });
                $('.login_phone_wrapper input').css({
                    height: 40,
                    borderRadius: 5,
                    padding: '3px 10px',
                    outline: 'none',
                    border: '1px solid #ccc'
                });
                $('.plogin_phone').css({ width: 280, });
                $('.plogin_phone_code').css({ width: 150,  float: 'left' });
                $('.plogin_btn_phone_code').css({
                    float: 'left',
                    marginLeft: 20,
                    width: 108,
                    textAlign: 'center'
                });
                $('.plogin_btn_phone').css({
                    width: 140,
                    background: '#1AAD19',
                    textAlign: 'center',
                    fontSize: 20,
                    color: '#fff',
                    display: 'block',
                    margin: '10px auto 0'
                });
                $('.plogin_close').css({
                    width: 25,
                    height: 25,
                    position: 'absolute',
                    top: -10,
                    right: -10,
                    background: '#ccc url(//i0.cy.com/www/pop/close.png) no-repeat center center',
                    backgroundSize: '90% 90%',
                    borderRadius: '50%'
                });
            }
            function eventCreate() {
                $('.plogin_btn_phone_code').click(function() {
                    var phone = $('.plogin_phone').val();
                    glob.ele.btnPhoneCode = '.plogin_btn_phone_code';
                    user.getCode(phone)
                });
                $('.plogin_btn_phone').click(function() {
                    var phone = $('.plogin_phone').val();
                    var code = $('.plogin_phone_code').val();
                    glob.ele.btnPhone = '.plogin_btn_phone';
                    glob.style.beforePhone.background = '#1AAD19';
                    var phoneInfo = user.loginPhone(phone, code);
                    if(phoneInfo.code === 10000) {
                        dialog.hideMask();
                        if(info.plat === glob.platform) utils.reload();
                        info.callback && info.callback();
                    }
                })
            }

            if ($('.login_phone_wrapper').length === 0) {
                htmlCreate();
                cssCreate();
                eventCreate();
            }
            dialog.popup($('.login_phone_wrapper'));
        },
        // 刀剑登录
        dlogin: function(scale) {
            function htmlCreate() {
                var html = '<div class="login_dj_wrapper ja_login_box">' +
                    '<h3 class="dlogin_title">登录账号</h3>' +
                    '<ul class="dlogin_list">' +
                        '<li>'+ 
                            '账号:<input type="text" class="dlogin_accout"/>' +
                            '<a href="http://bo.account.changyou.com/reg/contract.jsp?game=DJ" target="_blank" class=" dlogin_btn_phone_code">注册账号</a>' +
                        '</li>' +
                        '<li>' + 
                            '密码:<input type="password" class="dlogin_password"/>' +
                            '<a href="http://bo.account.changyou.com/pwd/changepwd.jsp" target="_blank" class=" dlogin_btn_phone_code">忘记密码</a>' +
                        '</li>' +
                        '<li>' + 
                            '验证码:<input type="text" maxlength="6" class="dlogin_code"/>' +
                            '<img class="dlogin_code_img dlogin_btn_chang" src="/wx/wxmsg/activitys/image/generate" alt="验证码">' +
                            '<a href="javascript:;" class=" dlogin_btn_chang">换一个</a>' +
                        '</li>' +
                        '<li style="padding-right: 40px;">' + 
                            '<span class="dloing_error"></span>' +
                            '<a href="javascript:;" class="dlogin_btn_login">登录</a>' + 
                        '</li>' +
                    '</ul>' +
                    '<a href="javascript:;" class="dlogin_close" ' +
                    'onclick="ja.hideMask($(this).parent())">✕</a>' +
                    '</div>';
                $('body').append(html);
            }
            function cssCreate() {
                $('.login_dj_wrapper').css({
                    width: 370, 
                    height: 290,
                    position: 'relation',
                    background: '#fff',
                    borderRadius: '2px',
                    fontSize: '14px',
                    transform: 'scale(' + (scale || (isMobile ? 1.8 : 1)) + ')'
                });
                $('.login_dj_wrapper *').css({ boxSizing: 'border-box' });
                $('.login_dj_wrapper a').css({
                    textDecoration: 'none',
                    color: '#0072C6',
                    padding: '2px 10px',
                    height: 38,
                    lineHeight: '32px',
                    fontSize: '12px'
                });
                $('.dlogin_list').css({ paddingLeft: 25 });
                $('.dlogin_list>li').css({ margin: '0 0 10px 10px',  overflow: 'hidden' });
                $('.dlogin_title').css({
                    textAlign: 'center',
                    margin: '20px 0 20px 0',
                    fontSize: 24,
                    fontWeight: 'normal'
                });
                $('.login_dj_wrapper input').css({
                    height: 30,
                    borderRadius: 2,
                    padding: '3px 10px',
                    outline: 'none',
                    border: '1px solid #ccc',
                    margin: '0 2px 0 10px'
                });
                $('.dlogin_code').css({ width: 90,  margin: '0 0 0 5px' });
                $('.dlogin_code_img').css({ vertivalAlign: 'middle',  marginBottom: -5 });
                $('.dlogin_btn_login').css({
                    width: 140,
                    background: '#1AAD19',
                    textAlign: 'center',
                    fontSize: 20,
                    color: '#fff',
                    display: 'block',
                    margin: '10px auto 0'
                });
                $('.dloing_error').css({
                    display: 'block',
                    color: '#ff6466',
                    fontSize: 12,
                    height: 16,
                    textAlign: 'center'
                });
                $('.dlogin_close').css({
                    width: 25,
                    height: 25,
                    padding: 0,
                    color: 'gray',
                    fontSize: 20,
                    fontWeight: 'bold',
                    position: 'absolute',
                    top: 3,
                    right: 10,
                    backgroundSize: '90% 90%',
                    borderRadius: '50%'
                });
            }
            function eventCreate() {
                // 换一个验证码
                $('.dlogin_btn_chang').click(function () {
                    var value = parseInt(Math.random()*10000);
                    $('.dlogin_code_img')
                        .attr('src', "/wx/wxmsg/activitys/image/generate?random_mark="+value)
                });
                // 登录
                $('.dlogin_btn_login').click(function() {
                    var account = $('.dlogin_accout').val(),
                        password = $('.dlogin_password').val(),
                        code = $('.dlogin_code').val(),
                        $error = $('.dloing_error');
                    if(!account) return $error.html('请输入账号');
                    if(!password) return $error.html('请输入密码');
                    if(!code) return $error.html('请输入验证码');
                    $error.html('');
                    $.ajax({
                        type:"post",
                        url: glob.originAll + glob.pathCore + "/djlogin?callback=" + encodeURI(location.href),
                        data:{
                            'cn': account,
                            'password': password,
                            'dj_nnex_code': code
                        },
                        success:function (outPut) {
                            $('.dlogin_btn_chang').click()
                            switch (outPut.login) {
                                case '000':
                                    $('.dlogin_accout').val('');
                                    $error.html('');
                                    dialog.hideMask($('.ja_login_box'));
                                    window.location.href = outPut.redirect;
                                    break;
                                case '001': $error.text('请输入账号'); break;
                                case '002':
                                case '003':
                                case '009': $error.text('账号错误，请重新输入'); break;
                                case '004': $error.text('您的账号异常，请尝试更换账号登陆'); break;
                                case '005': $error.text('账号或密码错误'); break;
                                case '006': $error.text('请输入密码'); break;
                                case '007': $error.text('请输入验证码'); break;
                                case '008': $error.text('验证码错误，请重新输入'); break;
                                case '099': $error.text('账号验证系统繁忙，请稍后再试'); break;
                                case '010': $error.text('活动已结束或未开始'); break;
                                
                                default:
                                    $error.text('系统繁忙，请稍后再试')

                                
                            }
                        }
                    });
                })
            }

            if ($('.login_dj_wrapper').length === 0) {
                htmlCreate();
                cssCreate();
                eventCreate();
            }
            dialog.popup($('.login_dj_wrapper'));
        }
    };
    var user = new User();
    /**
     * == 微信业务 ==
     **/
    function Wechat() {
    }
    Wechat.prototype = {
        // 微信初始化参数回去
        wxConfig: function() {
            var info;
            if(!glob.appId) return message.error('微信初始化需要appId，请联系后台开发添加');
            $.ajax({
                url: origin + '/wechat/web/' + glob.appId + '/config',
                async: false,
                success: function (data) {
                    if (data.config) {
                        info = data.config;
                    } else {
                        message.error('微信初始化失败，config接口异常，' + data.msg);
                    }
                }
            });
            return info;
        },
        // 微信初始化
        wxInit: function(fun) {
            if(glob.wxConfigInfo) {
                fun && fun();
            }else {
                var _this = this;
                $.getScript('https://res.wx.qq.com/open/js/jweixin-1.6.0.js', function() {
                    glob.wxConfigInfo = _this.wxConfig() || {};
                    var configInfo = glob.wxConfigInfo;
                    if(!configInfo.signature) {
                        message.error('微信初始化失败，/wechat/web/{appid}/config 没有获取到参数')
                        return
                    }
                    wx.config({
                        debug: glob.isWxDebug,     // 开启调试模式,调用的所有api的返回值会在客户端alert出来，若要查看传入的参数，可以在pc端打开，参数信息会通过log打出，仅在pc端时才会打印。
                        appId: configInfo.appId,           // 必填，公众号的唯一标识
                        timestamp: configInfo.timestamp,   // 必填，生成签名的时间戳
                        nonceStr: configInfo.nonceStr,     // 必填，生成签名的随机串
                        signature: configInfo.signature,   // 必填，签名，见附录1
                        jsApiList: [                        // 必填，需要使用的JS接口列表，所有JS接口列表见附录2
                            'translateVoice',           // 识别音频并返回识别结果接口
                            'onMenuShareTimeline',      // 分享到朋友圈
                            'onMenuShareAppMessage',    // 分享给朋友
                            'onMenuShareQQ',            // 分享到QQ
                            'onMenuShareQZone',         // 分享到QQ空间
                            'onMenuShareWeibo',         // 分享到腾讯微博
                            'hideMenuItems',            // 批量隐藏功能按钮接口
                            'showMenuItems',            // 批量显示功能按钮接口
                            'hideAllNonBaseMenuItem',   // 隐藏所有非基础按钮接口
                            'updateAppMessageShareData', // 分享给朋友/QQ（新）
                            'chooseWXPay' //微信支付
                        ]
                    });
                    fun && fun();
                })
            }
        },
        // 微信分享
        share: function (options) {
            if (isWechat) {
                var _options = {
                    type: 'link',
                    shareList: [
                        options.isNew ? 'updateAppMessageShareData' : 'onMenuShareAppMessage',    // 分享给朋友
                    ]
                };
                $.extend(_options, options);
                var list = _options.shareList,
                    hideAllNonBaseMenuItem = typeof _options['hideAllNonBaseMenuItem'] === 'boolean' ? _options['hideAllNonBaseMenuItem'] : true,
                    showList = _options.showMenuList,       // 要显示的分享渠道
                    hideList = _options.hideMenuList;       // 要显示的分享渠道

                delete _options['hideAllNonBaseMenuItem'];
                delete _options['isNew'];
                delete _options['shareList'];
                delete _options['showMenuList'];
                delete _options['hideMenuList'];

                function shareApi() {
                    wx.ready(function () {
                        for (var i in list) {
                            var shareType = list[i];
                            if (typeof wx[shareType] === 'function') {
                                wx[shareType](_options);
                            }
                        }
                        hideAllNonBaseMenuItem && wx.hideAllNonBaseMenuItem();
                        if(showList) {
                            wx.showMenuItems({ menuList: showList });
                        }else {
                            wx.showMenuItems({ menuList: [
                                    'menuItem:share:appMessage',
                                    'menuItem:favorite'
                                ]
                            });
                        }
                        if(hideList) {
                            wx.hideMenuItems({ menuList: hideList });
                        }
                    })
                }

                this.wxInit(function() {
                    if(glob.isWxReady) {
                        shareApi()
                        return
                    }
                    if(glob.isWxReady === false) {
                        var timerWxReady = setInterval(function() {
                            if(glob.isWxReady) {
                                shareApi()
                                clearInterval(timerWxReady)
                            }
                        }, 200)
                    }
                    glob.isWxReady = false
                    wx.ready(function () {
                        glob.isWxReady = true
                        shareApi()
                    })
                })
            }
        },
        // 微信分享事件统计
        shareLog: function(variable, fn) {
            if(!_glob.wechatInfo) return message.error('请先微信授权');
            if(isWechat) {
                var eventName = 'share';
                if(typeof variable === 'number') eventName = variable + ''
                if(typeof variable === 'string') eventName = variable;
                if(typeof variable === 'function') fn = variable;
                $.ajax({
                    type: 'POST',
                    url: '/shareLog',
                    data: {
                        event: eventName   // 分享事件
                    },
                    success: function (data) {
                        fn && fn(data)
                    }
                })
            }
        },
        // 查询当前微信是否绑定账号
        wxStatus: function () {
            var info = null;
            if(isWechat) {
                if(!glob.isWxLogin) message.error('请先设置 isWxLogin 为 true');
                if(_glob.wechatInfo) {
                    $.ajax({
                        type: 'POST',
                        url: glob.originOnly + '/wechat/auto/isbind',
                        async: false,
                        headers: {'PLAT': 'wechat'},
                        success: function (res) {
                            info = res;
                        }
                    });
                }
            }
            return info;
        },
        // 微信绑定用户，自动登录
        // 2023年8月14日 支持wegame|畅游|微信绑定三选一登录
        wxAutoLogin: function (code) {
            if (code === 1) {
                location.href = urlWxBind;
                return false;
            }
            if(isWechat) {
                $.ajax({
                    type: 'POST',
                    url: glob.originOnly + '/'+(_glob.platform == 'wgchangyou' ? 'wgchangyou' : 'wechat')+'/auto/autologin',
                    headers: {'PLAT': 'wechat'},
                    async: true,
                    success: function (res) {
                        if (res.code === 10000) {
                            utils.reload();
                        } else {
                            alert(res.message);
                        }
                    }
                });
            }
        }
    };
    var wechat = new Wechat();
    /**
     * == 活动特殊业务 ==
     **/
    function Activity() {
    }
    Activity.prototype = {
        // 龙门标识添加
        longmen: function (obj) {
            var imgN = 'longmen_test.png',
                $parent = $('body');
            obj = obj || {};
            if (obj.color === 'white' || obj.color === '#fff' || obj.color === '#fffff') {
                imgN = 'longmen_test_white.png'
            }
            if(obj.parent) {
                if(typeof obj.parent === 'string' || typeof obj.parent.length === 'undefined') {
                    $parent = $(obj.parent);
                }else if(typeof obj.parent === 'object') {
                    $parent = obj.parent;
                }
            }

            $('<img />').attr('src', imgHost + '/xtl/logo/' + imgN).css($.extend({
                width: 80,
                position: 'absolute',
                top: 20,
                left: 20,
                zIndex: 10
            }, obj)).appendTo($parent);
        },
        // 对当前地址拼接参数
        setUrlParams: function (val) {
            var str = '?infoData=',
                arr = [];
            for (var key in val) {
                var value = val[key] || typeof val[key] === 'number' ? val[key] : '';
                arr.push(key + '@@@' + encodeURIComponent(value));
            }
            return str + arr.join('@@@@');
        },
        // 获取当前路径或指定路径地址参数，与setUrlParams配合使用
        getUrlParams: function (url) {
            var json = {},
                info = this.getQueryString('infoData', url);
            if (info) {
                info.split('@@@@').forEach(function (item) {
                    var key = item.split('@@@')[0],
                        val = item.split('@@@')[1];
                    json[key] = decodeURIComponent(val);
                });
            }
            return json;
        },
        // 百度事件统计，原始
        baiduFormer: function () {
            message.error('百度【事件分析】收费了，该方法废弃')
        },
        // 百度事件统计，通用
        baiduEvent: function () {
            message.error('百度【事件分析】收费了，该方法废弃')
        },
        wxLoginFail: function() {
            storage.removeWechatInfo()
            utils.reload()
        },
        getTokenTime: function() {
            var timestamp = storage.getLUserInfo().timestamp || Date.now()
            return Date.now() - timestamp
        }
    }
    var activity = new Activity();

    /**
     * == 旧版本兼容 ==
     **/
    function OldVersion() {
    }
    OldVersion.prototype = {
        utils: {
            urlAddSearch: function(url) {
                var paramsObj = storage.getParams();
                url += paramsObj ? ('?' + paramsObj) : '';
                return !isIos && isWechat ? utils.urlAddKey(url) : url;
            },
            url_add_key: utils.urlAddKey,
            objType: function(val) {
                var json = {
                    '[object Object]': 'object',
                    '[object Array]': 'array',
                    '[object Number]': 'number',
                    '[object Function]': 'function',
                    '[object Null]': 'null',
                    '[object Undefined]': 'undefined',
                    '[object Boolean]': 'boolean',
                    "[object String]" : 'string'
                };
                return json[Object.prototype.toString.call(val)]
            },
            longmen: activity.longmen
        },
        client: {
            ajax: function (type, url, variate, fun, plat) {
                switch (typeof variate) {
                    case 'object':
                        if(variate.header) {
                            var header = variate.header;
                            delete variate.header;
                        }
                        if(variate.contentType) {
                            var contentType = variate.contentType;
                            delete variate.contentType;
                        }
                        var params = variate;
                        break;
                    case 'function': fun = variate; break;
                    case 'string': plat = variate; break;
                    default: message.error('client.ajax使用错误');
                }
                $.ajax({
                    type: type,
                    url: url,
                    data: params || {},
                    dataType: 'json',
                    cache: false,
                    xhrFields: { withCredentials: true },
                    contentType: contentType,
                    headers: header,
                    success: function(res) {
                        fun(res)
                    }
                })
            },
            common: function(type, url, variate, fun, plat) {
                var opt = glob;
                switch (typeof variate) {
                    case 'string': plat = variate; break;
                    case 'object': var data = variate; break;
                    case 'function': fun = variate; break;
                }
                var baseUrl = opt.host + '/' + (plat || opt.platform);
                this.ajax(opt.isDebug ? 'GET': type, baseUrl + url, data || {}, fun, plat);
            },
            get: function(url, variate, fun, plat) {
                this.common('GET',  url, variate, fun, plat);
            },
            post: function(url, variate, fun, plat) {
                this.common('POST', url, variate, fun, plat);
            }
        },
        common: {
            // 常用表单长度限制，class名要对应
            input: function() {
                $(that.options.ele.inputPhone).keyup(function() {
                    $(this).siblings('.error').text('');
                    if($(this).val().length > 11) $(this).val($(this).val().slice(0, 11))
                });        // 手机号
                $(that.options.ele.inputPhoneCode).keyup(function() {
                    $(this).siblings('.error').text('');
                    if($(this).val().length > 6) $(this).val($(this).val().slice(0, 6))
                });     // 手机验证码
            },
            // 移动端初始化
            mobile: function() {
                $('input').blur(function() { window.scrollTo(0, 0) });  // 解决 H5 在输入弹框后页面留白问题
            },
            // 输出最新全局对象 glob
            glob: function() {
                return that.glob;
            },
            // 百度事件统计
            baiduEvent: function(actName, sign, action, isPcM, isTwo) {
                // isPcM, isTwo 非必填，一般不用
                if(window._hmt) {
                    var cid = that.glob.cyscid
                        , tid = that.glob.cystid
                        , remark = isTwo ? ((cid ? ('cid=' + cid) : '无cid') + '/' + (tid ? ('tid=' + tid) : '无tid')) : (that.glob.cyscid || '无');
                    if(isPcM) remark += ('/' + (isMobile ? 'm' : 'pc'));
                    window._hmt.push(['_trackEvent', actName + sign, action + sign, remark + '/' +sign]);
                }else {
                    that.admin.error('请先添加百度统计代码');
                }
            }
        },
        http: {
            ajax: function (options) {
                $.ajax(options)
            },
            get: function(url, variate, fun) {
                var data = {};
                if(typeof variate === 'function') {
                    fun = variate;
                }else {
                    data = variate;
                }
                $.ajax({
                    type: 'GET',
                    url: glob.host + url,
                    data: data,
                    success: fun
                });
            },
            post: function(url, variate, fun, plat) {
                var data = {};
                if(typeof variate === 'function') {
                    fun = variate;
                }else {
                    data = variate;
                }
                $.ajax({
                    type: 'POST',
                    url: glob.host + url,
                    data: data,
                    success: fun
                });
            }
        },
        wx: {
            init: wechat.wxInit
        },
        user: {
            // 是否绑定微信
            wxIsBind: function(fun) {
                if(_glob.wechatInfo) {
                    $.ajax({
                        type: 'POST',
                        url: glob.originOnly + '/wechat/auto/isbind',
                        async: false,
                        headers: {'PLAT': 'wechat'},
                        success: function (res) {
                            fun && fun(res);
                        }
                    });
                }
            },
            loginAlert: function(plat) {
                user.login({ plat: plat });
            },
            loginUrl: function() {
                return user.login({ isUrl: true })
            }
        }
    };

    /**
     * == 活动开发，最终构造函数 ==
     **/
    var JoinActivity = function () {
        this.options = {
            app: undefined,             // 应用 初始化必传项
            activity: undefined,        // 活动 初始化必传项
            version: undefined,         // 版本 初始化必传项
            platform: undefined,        // 平台 初始化必传项
            type: 0,                    // 版本固定后，通过 type 值区分之前之后项目
            isUserInfo: true,           // 是否获取用户信息
            isWxOnly: false,            // 是否只是在微信中访问
            isWxLogin: false,           // 是否微信授权
            isAutoWxLogin: true,        // 是否进入页面就拉起微信授权
            isWxInit: false,            // 是否微信初始化
            isWxDebug: false,           // 是否开启微信debug调试
            isWxStatus: false,          // 是否查询微信绑定账号
            isDebug: false,             // 是否开启调试模式（只在debugDomain数组下域名生效）
            isVconsole: false,          // 是否启用vconsole（只在vconsoleDomain数组下域名生效）
            debugPath: '/config/json',  // debug 请求基础路径
            isAlert: true,              // 是否弹出活动异常弹窗
            isAlertLogin: true,         // 是否弹出登录异常弹窗
            isToken: false,             // 是否传递 token
            loginMethod: null,          // 登录方法名，默认
            host: $.inArray(location.host, arrHost) !== -1 ? location.protocol + '//join-activity.changyou.com' : origin,      // 接口请求域名，默认同域名
            wxShare: undefined,         // 微信分享内容
            excludePort: [],			// 不做防重点击处理接口
            wxTips: false,              // 是否显示微信授权提示
            async: true,                // 初始化接口是否async
            msg: {
                1106: '活动未开始',
                1103: '活动已结束',
                1102: '活动无效'
            },
            ele: {
                inputPhone: '.input_phone',
                inputPhoneCode: '.input_phone_code',
                btnPhone: '.btn_phone',
                btnPhoneCode: '.btn_phone_code',
                btnWxBind: '.btn_wx_bind'
            },
            style: {
                beforeCode: {background: '', 'pointer-events': 'auto'},
                afterCode: {background: '#9c9c9c', 'pointer-events': 'none'},
                beforePhone: {background: '', 'pointer-events': 'auto'},
                afterPhone: {background: '#9c9c9c', 'pointer-events': 'none'},
            },
            afterWxLoginFn: undefined,      // 微信授权后执行
            ready: undefined,   // 回调函数
        };
        this.glob = _glob;
        for(var key in _glob) {
            this[key] = _glob[key];
        }
    };
    JoinActivity.fn = JoinActivity.prototype = {
        config: function (options) {
            var opt = utils.deepMerge(this.options, options),           // 合并配参
                arrMust = ['app', 'activity', 'version', 'platform'],   // 初始化必填项，没有配置，给以提示
                _this = this;

            var show = new MidWare();

            // 配置异常判断
            // （1、必填项没填；2、platform = wechat，但不是在微信环境下；3、isWxOnly = true）
            show.use(function (about, next) {
                message.console(name + '-version', version);  // 输出ja版本号
                if (!isWechat && (opt.platform === 'wechat' || opt.isWxOnly)) {
                    return _this.output('请在微信中访问');
                }
                for (var i = 0; i < arrMust.length; i++) {
                    var item = arrMust[i];
                    if (!opt[item]) {
                        return _this.output(item + '为必填项');
                    } else
                        message.console(item, opt[item]);
                }
                var tokenTime = activity.getTokenTime()
                env != 'prod' && message.console('token', utils.timeToDate(tokenTime))
                utils.isLocalStorageEnabled()
                next();
            });

            // vconsole、isDebug、landscape 开启判断
            show.use(function (about, next) {
                if (opt.isDebug && $.inArray(location.host, debugDomain) === -1) {
                    opt.isDebug = false
                }
                if(opt.landscape && isMobile) {
                    utils.landscape()
                }
                if (opt.isVconsole && isMobile && $.inArray(location.host, vconsoleDomain) !== -1) {
                    utils.vconsole(function() {
                        next()
                    });
                }else {
                    next();
                }
            });

            // wegame 登录 检查 http 协议
            show.use(function (about, next) {
                if((opt.platform === 'wegame' || opt.platform === 'wgchangyou') && location.href.indexOf('http://') > -1) {
                    location.href = location.href.replace('http://', 'https://')
                }
                next();
            });

            // 配置无异常后，进行全局数据整理
            show.use(function (about, next) {
                glob.appName = [opt.app, opt.activity, opt.version, opt.platform].join('-');      // 当前活动唯一标识

                var urlCenter = opt.isDebug ? opt.debugPath : '',
                    storageParams = storage.getStrParams(),
                    params = utils.getParams();

                delete params.jcode;

                if(storageParams) params = $.extend(storageParams, params);

                storage.setStrParams(params);

                $.extend(glob, opt, {
                    pathCore: '/core/login/' + opt.app + '/' + opt.activity + '/' + opt.version,  // 通用接口中间段
                    originOnly: opt.host + urlCenter,
                    originAll: opt.host + urlCenter + '/' + opt.platform,
                    cyscid: params.CYSCID,
                    cystid: params.CYSTID
                });

                $.extend(_glob, {
                    app: opt.app,
                    activity: opt.activity,
                    version: opt.version,
                    platform: opt.platform,
                    params: params || {},
                    host: opt.host,
                    originOnly: glob.originOnly,
                    originAll: glob.originAll
                });

                next();
            });

            // 距离上次访问事件比较（同活动）
            show.use(function (about, next) {
                var oldTimestamp = storage.getTimestamp();
                if(oldTimestamp) {
                    // 大于1分钟，对错误码状态清空
                    if(Date.now() - oldTimestamp > 1 * 60 * 1000) {
                        storage.removeErrorCode();
                    }
                }
                storage.setTimestamp();
                next();
            });

            // 账号登录异常
            show.use(function(about, next) {
                var jcode = utils.getQueryString('jcode')
                if(jcode) {
                    if(opt.isAlertLogin && !_glob.isLogin) {
                        var errMsg = '';
                        switch (Number(jcode)) {
                            case 1001: errMsg = '登录异常'; break;
                            case 1007: errMsg = '网络繁忙'; break;
                            case 1300: errMsg = '畅游登录异常'; break;
                            case 3103: errMsg = '您的账号已封停'; break;
                            default: errMsg = '登录失败';
                        }
                        alert(errMsg);
                    }
                    // 错误日志：jcode 与 user/info 冲突
                    if(glob.isLogin) {
                        utils.log('地址栏有jcode码 且 账号登录成功')
                    }
                    utils.reload()
                    // history.pushState('', '', utils.deleteJcode(location.href))
                }
                next();
            });

            // 活动信息接口请求，拿到token、activityInfo、appId
            show.use(function (about, next) {
                setupAjax();
                user.getToken(function(infoInit) {
                    var item = infoInit.data || {};
                    $.extend(_glob, {
                        code: infoInit.code,
                        message: infoInit.message,
                        activityInfo: $.extend({}, item.activity, item.client)
                    });
                    $.extend(glob, {
                        token: item.token,
                        appId: item.activity && item.activity.wxId,
                        isForceMobileLogin: item.client && item.client.isForceMobileLogin
                    });
                    var userInfo = storage.getLUserInfo()
                    if(!userInfo.token || userInfo.token !== item.token) {
                        storage.setLUserInfo({
                            token: item.token,
                            timestamp: Date.now()
                        })
                    }
                    if (infoInit.code === 10000) {
                        setupAjax();
                        next();
                    } else {
                        var msg = glob.msg[_glob.code];
                        _this.output(glob.isAlert && msg);
                    }
                })
            });

            // 判断获取微信用户信息
            show.use(function (about, next) {
                // 微信环境下，平台配参为 wechat 或 需要微信授权
                if (isWechat && (opt.platform === 'wechat' || opt.isWxLogin)) {
                    var openWx = _glob.activityInfo.openWx  // 微信授权方式
                    var wechatInfo = storage.getWechatInfo()

                    // 缓存不存在 或者 不满足授权方式，请求后端接口
                    if(
                        !wechatInfo ||
                        (!(openWx === 2 && wechatInfo && wechatInfo.nickname)) ||
                        Date.now() - wechatInfo.createTime > 2 * 60 * 60 * 1000
                    ) {
                        _glob.wechatInfo = user.getUserInfo('wechat');
                        if(_glob.wechatInfo) {
                            storage.setWechatInfo($.extend(_glob.wechatInfo, {
                                createTime: Date.now()
                            }))
                        }
                    }else {
                        _glob.wechatInfo = wechatInfo
                    }

                    // 静默授权
                    if(openWx === 1) {
                        _glob.isWLogin = !!_glob.wechatInfo;
                    }
                    // 用户授权
                    if(openWx === 2) {
                        _glob.isWLogin = !!(_glob.wechatInfo && _glob.wechatInfo.nickname)
                    }
                    // 平台是 wechat，同步 isLogin 和 userInfo 参数
                    if(opt.platform === 'wechat') {
                        _glob.isLogin = _glob.isWLogin
                        _glob.userInfo = _glob.wechatInfo
                    }
                    // 未授权处理
                    if(!_glob.isWLogin || _glob.wechatInfo.dataStatus == 2) {
                        // 授权失败：触发授权后 回来再次查询
                        if(glob.isWechatLogin) {
                            alert('微信授权失败')
                            glob.isWechatLogin = false
                        }
                        // 自动授权判断
                        if(opt.isAutoWxLogin || openWx === 1) {
                            user.login({plat: 'wechat'});
                            return
                        }
                    }
                    // 授权成功处理
                    else {
                        opt.isUserInfo = glob.platform !== 'wechat'
                    }
                    next();
                }else {
                    next();
                }
            });

            // 查询微信是否绑定账号信息
            show.use(function (about, next) {
                if (_glob.isWLogin && opt.isWxStatus) {
                    var wxStatusInfo = wechat.wxStatus();
                    if (wxStatusInfo.code === 10000) {
                        _glob.wxBindName = typeof wxStatusInfo.data == 'string' ? wxStatusInfo.data : wxStatusInfo.data.cn;
                        _glob.wxBindType = wxStatusInfo.data.type;
                    }
                    next();
                } else
                    next();
            });

            // 再获取账号用户账号信息，如果得不到，则为未登录状态
            show.use(function (about, next) {
                if (opt.isUserInfo) {
                    _glob.userInfo = user.getUserInfo();
                    _glob.isLogin = !!_glob.userInfo;
                    if(_glob.isLogin) {
                        if(_glob.platform === 'wgchangyou') {
                            storage.setLoginType(_glob.userInfo && _glob.userInfo.nickname ? 'W' : 'C')
                            setupAjax();
                        }
                    }else {
                        storage.removeLoginType()  // 如果未登录状态，清除登录类型
                    }
                    next();
                } else
                    next();
            });

            // 微信授权后，检查 wechatSign 标识并执行
            show.use(function (about, next) {
                if(storage.getWechatSign()) {
                    setTimeout(function() {
                        storage.removeWechatSign()
                    }, 600)
                }
                next();
            });

            // 判断微信是否初始化、和微信分享
            show.use(function (about, next) {
                isWechat && opt.wxShare && wechat.share(opt.wxShare);
                next();
            });

            // 最终输出，给到初始化结果
            show.use(function () {
                _this.output();
            });

            // 执行
            show.handleRequest();
        },
        output: function(msg) {
            if (typeof msg === 'string') alert(msg);
            for(var key in _glob) {
                this[key] = _glob[key];
            }
            glob.ready && glob.ready(_glob);    // 兼容配置项中的回调 ready函数

            // 监听ready变化和执行
            Object.defineProperty(glob, 'ready', {
                set: function(fun) {
                    fun && fun(_glob);
                }
            });
        },
        ready: function (fun) {
            glob.ready = fun;
        },
        utils: utils,
        user: user,
        wx: wechat
    };

    /************************************* 执行 ***********************************/
    /* == 工具类模块 == */
    Mixin(JoinActivity, Utils);
    Mixin(JoinActivity, Dialog);
    Mixin(JoinActivity, Message);
    Mixin(JoinActivity, Verify);

    /* == 业务类模块 == */
    Mixin(JoinActivity, User);
    Mixin(JoinActivity, Activity);
    Mixin(JoinActivity, Wechat);
    Mixin(JoinActivity, Storage);

    /* == 与旧版方法深层合并 == */
    MixinDeep(JoinActivity, OldVersion);

    window[name] = new JoinActivity();

}(window));
